package com.abeir.bilibili.convert;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;

public abstract class AbstractMediaScanner implements Scanner{

    private final String playurlFilename;
    private final String suffix;

    public AbstractMediaScanner(String playurlFilename, String suffix){
        this.playurlFilename = playurlFilename;
        this.suffix = suffix;
    }

    public abstract Optional<String> findBaseUrlFromJSON(JSONObject rootJSONObject);

    protected String getSuffix() {
        return suffix;
    }

    protected String getPlayurlFilename() {
        return playurlFilename;
    }

    @Override
    public Optional<File> target(Path dir) {
        File[] mediaFiles = findMediaFiles(dir);
        File playurlFile = findPlayurlFile(dir);

        byte[] data;
        try {
            data = Files.readAllBytes(playurlFile.toPath());
        } catch (IOException e) {
            throw new FileSystemNotFoundException("Cannot read " + this.playurlFilename + " file.");
        }
        return findVideoFile(JSON.parseObject(data), mediaFiles);
    }

    private File[] findMediaFiles(Path dir){
        File[] files = dir.toFile().listFiles((d, name) -> name.endsWith(suffix));
        if(files == null || files.length == 0){
            throw new IllegalArgumentException("Not media files found by suffix " + this.suffix);
        }
        return files;
    }

    private File findPlayurlFile(Path dir){
        File[] files = dir.toFile().listFiles((d, name) -> name.equals(playurlFilename));
        if(files == null || files.length == 0){
            throw new IllegalArgumentException("Not playurl file found " + this.playurlFilename);
        }
        if(files.length > 1){
            throw new IllegalArgumentException("Multiple " + this.playurlFilename + " files were discovered.");
        }
        return files[0];
    }

    private Optional<File> findVideoFile(JSONObject json, File[] mediaFiles){
        Optional<String> baseUrl = findBaseUrlFromJSON(json);
        if(baseUrl.isEmpty()){
            throw new IllegalArgumentException("Not baseUrl or base_url element found in JSON.");
        }
        for(File file : mediaFiles){
            if(baseUrl.get().contains(file.getName())){
                return Optional.of(file);
            }
        }
        return Optional.empty();
    }
}
